package cc.rengu.igas.mcps.core.service.trans.cardpay;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.channel.cups.facade.bean.CupsTermInfo;
import cc.rengu.igas.channel.cups.facade.request.PreAuthRequest;
import cc.rengu.igas.channel.cups.facade.response.PreAuthResponse;
import cc.rengu.igas.mcps.common.constant.McpsParamConstant;
import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.enums.McpsAcctTypeEnum;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.model.AcctAndFeeType;
import cc.rengu.igas.mcps.core.model.PosTransInfo;
import cc.rengu.igas.mcps.core.realize.PosParamDealService;
import cc.rengu.igas.mcps.core.realize.impl.PosParamDealServiceImpl;
import cc.rengu.igas.mcps.core.service.base.AuthService;
import cc.rengu.igas.mcps.facade.base.Header;
import cc.rengu.igas.mcps.facade.request.PosCardPreAuthRequest;
import cc.rengu.igas.mcps.facade.response.PosCardPreAuthResponse;
import cc.rengu.igas.share.common.dao.RoleAcctInfoMapper;
import cc.rengu.igas.share.common.dao.impl.RoleAcctInfoMapperImpl;
import cc.rengu.igas.share.common.entity.RoleAcctInfo;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.BinInfoService;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.BinInfoServiceImpl;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 银行卡预授权.
 */
public class PosCardPreAuthService extends AuthService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        PosCardPreAuthRequest posCardPreAuthRequest = new PosCardPreAuthRequest();
        ConvertUtil.convertOutput(posCardPreAuthRequest);
        return posCardPreAuthRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        BizResponse bizResponse = new BizResponse();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        PosCardPreAuthRequest posCardPreAuthRequest = (PosCardPreAuthRequest) request;
        PosCardPreAuthResponse posCardPreAuthResponse = new PosCardPreAuthResponse();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String newPin = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.PIN_DATA);
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        //初始化用户订单表
        UserOrderInfo preAuthUserOrderInfo = initOrderInfoUser(posCardPreAuthRequest);
        //初始化商户订单表
        MchntOrderInfo preAuthMchntOrderInfo = initOrderInfoMchnt(posCardPreAuthRequest, preAuthUserOrderInfo);
        //获取卡BIN信息并判断是否支持此类卡的渠道交易
        /*获取卡号*/
        String cardNo = posCardPreAuthRequest.getPayAcctNo();
        /*获取终端信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntTermInfo mchntTermInfo = mchntService.getMchntTermInfo(instId, posCardPreAuthRequest.getMchntNo(), posCardPreAuthRequest.getTermNo());
        /*获取账户类型与费率类型*/
        AcctAndFeeType acctAndFeeType = (AcctAndFeeType) xmlTreeUtil.getXmlTreeObjectValue(McpsTreeNodeConstant.ACCT_AND_FEE_TYPE, AcctAndFeeType.class);
        /*创建通道支付订单*/
        List<ChannelCallCfg> cupsChannelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> item.getCallChannelId().equals(ChannelEnum.CUPS.getChannelType())).sorted(Comparator.comparing(ChannelCallCfg::getCallIndex)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = cupsChannelCallCfgList.get(0);
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        String referenceNo = posParamDealService.getRefNo();
        posCardPreAuthResponse.setReferenceNo(referenceNo);
        PayOrderInfo preAuthPayOrderInfo = initPayOrderInfo(preAuthUserOrderInfo, preAuthMchntOrderInfo, posCardPreAuthRequest, channelCallCfg.getCallIndex(), channelCallCfg.getCallChannelId(), acctAndFeeType.getAcctType(), referenceNo, mchntTermInfo.getTermType());
        /*登记订单*/
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
        mchntOrderInfoList.add(preAuthMchntOrderInfo);
        OrderService orderService = new OrderServiceImpl();
        /*登记*/
        if (!orderService.registerOrderInfo(preAuthUserOrderInfo, mchntOrderInfoList, preAuthPayOrderInfo)) {
            rglog.error("订单登记失败");
            throw new BizException(RespCodeEnum.REGISTER_ORDER_ERROR.getRespCode(), RespCodeEnum.REGISTER_ORDER_ERROR.getRespCode());
        }
        /*银数预授权*/
        if (preAuthPayOrderInfo.getPayerAcctType().equals(McpsAcctTypeEnum.OWN_CREDIT.getAcctType())) {
            updcPreAuth(posCardPreAuthRequest, newPin, preAuthMchntOrderInfo, preAuthUserOrderInfo, preAuthPayOrderInfo);
        }
        /*银联预授权*/
        if (preAuthPayOrderInfo.getPayerAcctType().equals(McpsAcctTypeEnum.OTHER_DEBIT.getAcctType()) || preAuthPayOrderInfo.getPayerAcctType().equals(McpsAcctTypeEnum.OTHER_CREDIT.getAcctType())) {
            cupsPreAuth(posCardPreAuthRequest, newPin, preAuthMchntOrderInfo, preAuthUserOrderInfo, preAuthPayOrderInfo, mchntTermInfo, posCardPreAuthResponse, referenceNo);
        }
        /*组装返回报文*/
        posCardPreAuthResponse.setHeader(posCardPreAuthRequest.getHeader());
        //TODO 待修改
        Header header = new Header();
        BeanUtil.beanCopy(posCardPreAuthRequest.getHeader(), header);
        posCardPreAuthResponse.setHeader(header);
        posCardPreAuthResponse.setPayId(sysSeqNum);
        //预授权编号
        posCardPreAuthResponse.setTransAuthCode(preAuthPayOrderInfo.getTxnAuthCode());
        bizResponse.setRspSysId(AppParamConstant.IGAS);
        bizResponse.setRespCode(preAuthPayOrderInfo.getRespCode());
        bizResponse.setRespDesc(preAuthPayOrderInfo.getRespDesc());
        bizResponse.setResult(posCardPreAuthResponse);
        return bizResponse;
    }


    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        PosCardPreAuthResponse posCardPreAuthResponse = (PosCardPreAuthResponse) bizResponse.getResult();
        posCardPreAuthResponse.setRespCode(bizResponse.getRespCode());
        posCardPreAuthResponse.setRespDesc(bizResponse.getRespDesc());
        ConvertUtil.convertInput(posCardPreAuthResponse);
    }

    /**
     * 登记用户订单表
     *
     * @param posCardPreAuthRequest 请求信息
     * @throws Exception 异常
     */
    private UserOrderInfo initOrderInfoUser(PosCardPreAuthRequest posCardPreAuthRequest) throws Exception {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /*获取机构号*/
        String instId = posCardPreAuthRequest.getHeader().getInstId();
        /*获取交易码*/
        String txnNum = posCardPreAuthRequest.getHeader().getTxnNum();
        /*获取业务细分*/
        String bizType = posCardPreAuthRequest.getHeader().getBizType();
        /*获取源系统标识*/
        String msgSrcId = posCardPreAuthRequest.getHeader().getSrcSysId();
        userOrderInfo.setUserOrderId(sysSeqNum);
        userOrderInfo.setMchntOrderId(sysSeqNum);
        userOrderInfo.setInstId(instId);
        userOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        userOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        userOrderInfo.setTxnNum(txnNum);
        userOrderInfo.setBizType(bizType);
        userOrderInfo.setMsgSrcId(msgSrcId);
        userOrderInfo.setTransChannelId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_CHANNEL_ID));
        userOrderInfo.setFrontSeqNum(posCardPreAuthRequest.getHeader().getTraceNo());
        userOrderInfo.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        userOrderInfo.setOrderCreateTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"));
        userOrderInfo.setOrderExpiryTime(DateUtil.getDateByTimeStamp(System.currentTimeMillis() + 5 * 60 * 1000, "yyyyMMddHHmmss"));
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setOrderAmt(posCardPreAuthRequest.getTransAmt());
        return userOrderInfo;
    }

    /**
     * 登记商户订单表
     *
     * @param posCardPreAuthRequest 请求信息
     * @throws Exception 异常
     */
    private MchntOrderInfo initOrderInfoMchnt(PosCardPreAuthRequest posCardPreAuthRequest, UserOrderInfo userOrderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntOrderInfo mchntOrderInfo = new MchntOrderInfo();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        /*获取商户基本信息*/
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(posCardPreAuthRequest.getHeader().getInstId(), posCardPreAuthRequest.getMchntNo());
        if (null == mchntInfo) {
            rglog.error("查询商户基本信息失败<{}>", posCardPreAuthRequest.getMchntNo());
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*内部树复制会把订单状态保存到商户订单信息表*/
        BeanUtil.beanCopy(userOrderInfo, mchntOrderInfo);
        /*设置操作员id*/
        mchntOrderInfo.setUserId(posCardPreAuthRequest.getUserId());
        /*设置商户订单表中业务产品代码*/
        mchntOrderInfo.setBizProdCode(txnInfo.getSrcTxnAuthCfg().getBizProdCode());
        /*商户订单号*/
        mchntOrderInfo.setMchntOrderId(sysSeqNum);
        //终端号 added by wukefan  at 20200602
        mchntOrderInfo.setTermNo(posCardPreAuthRequest.getTermNo());
        /*收单机构号 */
        mchntOrderInfo.setAcqInstCode(mchntInfo.getSignInstId());
        /*行业类别*/
        mchntOrderInfo.setIndustryType(mchntInfo.getIndustryType());
        /*商户号*/
        mchntOrderInfo.setMchntNo(posCardPreAuthRequest.getMchntNo());
        /*若存在 设置连锁商户门店*/
        if (null != mchntInfo.getChainMchntNo()) {
            mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
        }
        /*商户名称*/
        mchntOrderInfo.setMchntName(mchntInfo.getMchntName());
        /*交易币种*/
        mchntOrderInfo.setOrderCcy(AppParamConstant.DEFAULT_ORDER_CCY);
        /*订单金额*/
        mchntOrderInfo.setOrderAmt(posCardPreAuthRequest.getTransAmt());
        /*交易金额*/
        mchntOrderInfo.setRealSettleAmt(posCardPreAuthRequest.getTransAmt());
        /*实时清算标识*/
        mchntOrderInfo.setRealSettleFlag(mchntInfo.getRealSettleFlag());
        /*设置交易状态*/
        mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        /*设置业务状态*/
        mchntOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        //实时清算标志 added by wukefan at 20200602
        mchntOrderInfo.setRealSettleFlag(mchntInfo.getRealSettleFlag());
        /*创建时间*/
        mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        return mchntOrderInfo;
    }

    /**
     * 登记支付订单表
     *
     * @param posCardPreAuthRequest 请求信息
     * @throws Exception 异常
     */
    private PayOrderInfo initPayOrderInfo(UserOrderInfo userOrderInfo, MchntOrderInfo mchntOrderInfo, PosCardPreAuthRequest posCardPreAuthRequest, String dstCallIndex, String channelId, String acctType, String referenceNo, String deviceType) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* 登记支付订单信息 */
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String txnNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_NUM);
        String bizType = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.BIZ_TYPE);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        /* 生成支付订单号 */
        String payOrderId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        xmlTreeUtil.setXmlTreeStringValue(McpsTreeNodeConstant.ORDER_ID, payOrderId);
        /**/
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*获取本行内部渠道户*/
        RoleAcctInfoMapper roleAcctInfoMapper = new RoleAcctInfoMapperImpl();
        RoleAcctInfo roleAcctInfo = new RoleAcctInfo();
        /*区分 本他行 获取本行渠道户 或者 银联渠道户*/
        if (McpsAcctTypeEnum.OTHER_DEBIT.getAcctType().equals(acctType) || McpsAcctTypeEnum.OTHER_CREDIT.getAcctType().equals(acctType)) {
            /*银联渠道户*/
            roleAcctInfo = roleAcctInfoMapper.selectBankRoleAcctInfoBySettleAcctId(instId, "CUPS_PAYCHNL_SUBJECT", instId + McpsParamConstant.DEFAULT_TOP_INST_ID);
        } else {
            /*本行内部渠道户*/
            roleAcctInfo = roleAcctInfoMapper.selectBankRoleAcctInfoBySettleAcctId(instId, "BANK_PAYCHNL_SUBJECT", instId + McpsParamConstant.DEFAULT_TOP_INST_ID);
        }
        PayOrderInfo payOrderInfo = new PayOrderInfo();
        payOrderInfo.setSysSeqNum(sysSeqNum);
        payOrderInfo.setMchntOrderId(sysSeqNum);
        payOrderInfo.setInstId(instId);
        payOrderInfo.setMchntNo(posCardPreAuthRequest.getMchntNo());
        payOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        payOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        payOrderInfo.setTxnNum(txnNum);
        payOrderInfo.setBizType(bizType);
        payOrderInfo.setTransBatchNo(" ");
        payOrderInfo.setOrderCcy(AppParamConstant.DEFAULT_ORDER_CCY);
        payOrderInfo.setOrderAmt(posCardPreAuthRequest.getTransAmt());
        payOrderInfo.setMsgDstId(ChannelEnum.CUPS.getChannelType());
        /*设置通到序号*/
        String strIndex = xmlTreeUtil.getXmlTreeStringValue("currentDstCallIndex");
        Integer acctCallIndex = new Integer((StringUtil.isEmptyOrNull(strIndex)) ? "0" : strIndex);
        String dstAcctCallIndex = Integer.toString(acctCallIndex + 1);
        payOrderInfo.setDstCallIndex(acctCallIndex.toString());
        xmlTreeUtil.setXmlTreeStringValue("currentDstCallIndex", dstAcctCallIndex);
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.PROCESSING.getStatus());
        payOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        payOrderInfo.setChannelOrderId(sysSeqNum);
        /*通道标示*/
        payOrderInfo.setMsgDstId(ChannelEnum.CUPS.getChannelType());
        if (McpsAcctTypeEnum.OWN_DEBIT.getAcctType().equals(acctType) || McpsAcctTypeEnum.OWN_CREDIT.getAcctType().equals(acctType)) {
            payOrderInfo.setPayType(PayTypeEnum.BANK_CARD.getPayType());
            payOrderInfo.setChannelReconKey(payOrderInfo.getChannelOrderId());
            /*通道交易码*/
            payOrderInfo.setDstTxnNum("01000306");
        } else if (McpsAcctTypeEnum.OTHER_DEBIT.getAcctType().equals(acctType) || McpsAcctTypeEnum.OTHER_CREDIT.getAcctType().equals(acctType)) {
            /*对账唯一key*/
            payOrderInfo.setChannelReconKey(posParamDealService.getCupsReconKey(instId, mchntOrderInfo.getMchntNo()));
            /*通道类型*/
            payOrderInfo.setDstChannelType(ChannelEnum.CUPS.getChannelType());
            /*支付方式*/
            payOrderInfo.setPayType(PayTypeEnum.OTHER_BANK_CARD.getPayType());
            ChannelCallCfg channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> ChannelEnum.CUPS.getChannelType().equals(item.getCallChannelId())).collect(Collectors.toList()).get(0);
            /*通道交易码*/
            payOrderInfo.setDstTxnNum(channelCallCfgList.getCallChannelTxn());
        }

        payOrderInfo.setPayerAcctType(acctType);
        payOrderInfo.setPayerAcctInfo(posCardPreAuthRequest.getPayAcctNo());
        if (null != roleAcctInfo && null != roleAcctInfo.getActualAcct()) {
            payOrderInfo.setPayeeAcctInfo(roleAcctInfo.getActualAcct());
        }
        payOrderInfo.setRealPayAmt(posCardPreAuthRequest.getTransAmt());
        PosTransInfo posTransInfo = new PosTransInfo();
        posTransInfo.setTermRead(posCardPreAuthRequest.getTermRead());
        posTransInfo.setIcConCode(posCardPreAuthRequest.getIcConCode());
        posTransInfo.setRefNo(referenceNo);
        posTransInfo.setDeviceType(deviceType);
        BeanUtil.beanCopy(posCardPreAuthRequest, posTransInfo);
        payOrderInfo.setPayerRemark(Base64.encodeBase64String(JSONObject.toJSONString(posTransInfo).getBytes()));
        return payOrderInfo;
    }

    /*银数预授权*/
    private void updcPreAuth(PosCardPreAuthRequest posCardPreAuthRequest, String newPin, MchntOrderInfo preAuthMchntOrderInfo, UserOrderInfo preAuthUserOrderInfo, PayOrderInfo preAuthPayOrderInfo) throws Exception {
        /*设置dubbo服务*/
        DubboService dubboService = new DubboServiceImpl();
        /**/
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*设置订单服务*/
        OrderService orderService = new OrderServiceImpl();
        /*设置 商户订单 list*/
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /*获取商户号*/
        String mchntNo = posCardPreAuthRequest.getMchntNo();
        /*设置预授权请求报文*/
        // TODO 银数预授权
        // （1） 调用失败，更新订单状态为失败
        // （2） 调用超时，更新订单为超时
        // （3） 调用成功，更新三张订单表状态为成功
    }

    /*银联预授权*/
    private void cupsPreAuth(PosCardPreAuthRequest posCardPreAuthRequest, String newPin, MchntOrderInfo preAuthMchntOrderInfo, UserOrderInfo preAuthUserOrderInfo, PayOrderInfo preAuthPayOrderInfo, MchntTermInfo mchntTermInfo, PosCardPreAuthResponse posCardPreAuthResponse, String refNo) throws Exception {
        /*设置dubbo服务*/
        DubboService dubboService = new DubboServiceImpl();
        /**/
        PosParamDealService posParamDealService = new PosParamDealServiceImpl();
        /*设置订单服务*/
        OrderService orderService = new OrderServiceImpl();
        /*设置 商户订单 list*/
        List<MchntOrderInfo> mchntOrderInfoList = new ArrayList<>();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /*获取商户号*/
        String mchntNo = posCardPreAuthRequest.getMchntNo();
        /*获取机构号*/
        String instId = posCardPreAuthRequest.getHeader().getInstId();
        /*获取系统流水号*/
        String sysNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("获取商户信息失败!");
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*获取卡bin信息*/
        BinInfoService binInfoService = new BinInfoServiceImpl();
        BinInfo binInfo = binInfoService.getCardBinInfo(posCardPreAuthRequest.getPayAcctNo());
        /*设置预授权请求报文*/
        PreAuthRequest preAuthRequest = new PreAuthRequest();
        cc.rengu.igas.channel.cups.facade.base.Header header = new cc.rengu.igas.channel.cups.facade.base.Header();
        BeanUtil.beanCopy(posCardPreAuthRequest.getHeader(), header);
        /*获取银联pos预授权交易代码*/
        header.setTxnNum(preAuthPayOrderInfo.getDstTxnNum());
        /*外围流水号赋值*/
        header.setTraceNo(preAuthPayOrderInfo.getChannelOrderId());
        preAuthRequest.setHeader(header);
        preAuthRequest.setCupsTraceNo(sysNum.substring(sysNum.length() - 6));
        preAuthRequest.setTransDateTime(preAuthPayOrderInfo.getTxnDate().substring(4, 8) + preAuthPayOrderInfo.getTxnTime());
        preAuthRequest.setNoPinFlag(mchntInfo.getNoPasswordFlag());
        preAuthRequest.setPinData(newPin);
        preAuthRequest.setNoPinFlag(mchntInfo.getNoPasswordFlag());
        preAuthRequest.setCupsMchntNo(mchntInfo.getCupsMchntNo());
        preAuthRequest.setMchntNo(preAuthRequest.getMchntNo());
        preAuthRequest.setTermNo(posCardPreAuthRequest.getTermNo());
        preAuthRequest.setMchntShortName(mchntInfo.getMchntSimpleName());
        preAuthRequest.setMchntType(preAuthMchntOrderInfo.getIndustryType());
        String acqInstCode = posParamDealService.genCupsAcqInstCode(instId, posCardPreAuthRequest.getMchntNo());
        String fwdInstCode = XmlConfigUtil.getXmlConfigCacheKeyValue(CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_FWD_INS_CODE);
        preAuthRequest.setCupsInstCode(acqInstCode);
        preAuthRequest.setFwdInstCode(fwdInstCode);
        preAuthRequest.setOrderAmt(preAuthPayOrderInfo.getOrderAmt());
        preAuthRequest.setOrderCcy(McpsParamConstant.INNER_DEFAULT_ORDERCCY);
        preAuthRequest.setPayAcctNo(posCardPreAuthRequest.getPayAcctNo());
        //TODO 待修改
        preAuthRequest.setTrack2Data(posCardPreAuthRequest.getTrack2Data());
        preAuthRequest.setTrack3Data(posCardPreAuthRequest.getTrack3Data());
        preAuthRequest.setReferenceNo(refNo);
        preAuthRequest.setCardExpireDate(posCardPreAuthRequest.getCardexpireDate());
        preAuthRequest.setEntryMode(posCardPreAuthRequest.getEntryMode());
        preAuthRequest.setCardSeqNo(posCardPreAuthRequest.getCardSeqNo());

        /*55域 卡数据*/
        preAuthRequest.setIcData(posCardPreAuthRequest.getIcData());

        preAuthRequest.setIcConCode(posCardPreAuthRequest.getIcConCode());
        preAuthRequest.setSecCtrlInfo(posCardPreAuthRequest.getTrack2Data());
        /*设置终端信息*/
        CupsTermInfo cupsTermInfo = new CupsTermInfo();
        BeanUtil.beanCopy(posCardPreAuthRequest.getTermInfo(), cupsTermInfo);
        if (StringUtil.isEmptyOrNull(cupsTermInfo.getDeviceType())) {
            cupsTermInfo.setDeviceType(mchntTermInfo.getTermType());
        }
        preAuthRequest.setTermInfo(cupsTermInfo);
        preAuthRequest.setTermRead(posCardPreAuthRequest.getTermRead());
        /*打印报文*/
        rglog.info("银联请求报文preAuthRequest：<{}>", JSON.toJSONString(preAuthRequest));
        cc.rengu.igas.channel.cups.facade.result.Result<PreAuthResponse> result = (cc.rengu.igas.channel.cups.facade.result.Result<PreAuthResponse>) dubboService.callDubboService("cupsPayService", "preAuth", preAuthRequest);
        rglog.debug("dubbo调用预处理结果：{}", JSON.toJSONString(result));
        /*撤销失败处理*/
        if (null == result || null == result.getResult() || (!result.getResult().getRespCode().equals(McpsParamConstant.DUBBO_SUCCESS) && !result.getResult().getRespCode().equals(McpsParamConstant.DUBBO_OVERTIME) && !McpsParamConstant.COMMUNICATION_OVERTIME.equals(result.getResult().getRespCode()))) {
            rglog.debug("返回失败：{}", result.getResult().getRespCode());
            preAuthPayOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            preAuthPayOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            preAuthMchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            preAuthMchntOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            preAuthUserOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            preAuthUserOrderInfo.setBizStatus(BizStatusEnum.FAILED.getStatus());
            if (!orderService.updateOrderInfo(preAuthUserOrderInfo, Arrays.asList(preAuthMchntOrderInfo), preAuthPayOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
            /*设置返回码 返回信息*/
            if (null == result || !result.isSuccess()) {
                preAuthPayOrderInfo.setRespCode(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
                preAuthPayOrderInfo.setRespDesc(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
            } else {
                preAuthPayOrderInfo.setRespCode(result.getResult().getRespCode());
                preAuthPayOrderInfo.setRespDesc(result.getResult().getRespDesc());
            }
        }
        /*超时处理*/
        else if (result.isSuccess() && (McpsParamConstant.DUBBO_OVERTIME.equals(result.getResult().getRespCode()) || McpsParamConstant.COMMUNICATION_OVERTIME.equals(result.getResult().getRespCode()))) {
            /*更新支付订单*/
            preAuthPayOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            preAuthPayOrderInfo.setRespCode(result.getResult().getRespCode());
            preAuthPayOrderInfo.setRespDesc(result.getResult().getRespCode());
            /*更新商户订单*/
            preAuthMchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            mchntOrderInfoList.add(preAuthMchntOrderInfo);
            /*更新支付订单*/
            preAuthPayOrderInfo.setRespCode(result.getResult().getRespCode());
            preAuthPayOrderInfo.setRespDesc(result.getResult().getRespDesc());
            preAuthUserOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            /*更新*/
            if (!orderService.updateOrderInfo(preAuthUserOrderInfo, mchntOrderInfoList, preAuthPayOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        }
        /*成功处理*/
        else {
            /*更新三张订单状态为成功*/
            /*用户订单*/
            preAuthUserOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            preAuthUserOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            preAuthUserOrderInfo.setBizStatus(BizStatusEnum.AUTH_INCOMPLETE.getStatus());
            /*商户订单*/
            preAuthMchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            preAuthMchntOrderInfo.setBizStatus(BizStatusEnum.AUTH_INCOMPLETE.getStatus());
            mchntOrderInfoList.add(preAuthMchntOrderInfo);
            /*支付订单*/
            preAuthPayOrderInfo.setTxnAuthCode(result.getResult().getAuthCode());
            preAuthPayOrderInfo.setRespCode(result.getResult().getRespCode());
            preAuthPayOrderInfo.setRespDesc(result.getResult().getRespDesc());
            preAuthPayOrderInfo.setSettleDate(result.getResult().getSettleDate());
            preAuthPayOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            preAuthPayOrderInfo.setBizStatus(BizStatusEnum.AUTH_INCOMPLETE.getStatus());
            /*更新*/
            if (!orderService.updateOrderInfo(preAuthUserOrderInfo, mchntOrderInfoList, preAuthPayOrderInfo)) {
                rglog.error("订单表更新失败");
                throw new BizException(RespCodeEnum.UPDATE_ORDER_ERROR.getRespCode(), RespCodeEnum.UPDATE_ORDER_ERROR.getRespDesc());
            }
        }

        /*设置返回码 返回信息*/
        if (null == result || !result.isSuccess()) {
            posCardPreAuthResponse.setRespCode(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
            posCardPreAuthResponse.setRespDesc(OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
        } else {
            posCardPreAuthResponse.setRespCode(result.getResult().getRespCode());
            posCardPreAuthResponse.setRespDesc(result.getResult().getRespDesc());
            posCardPreAuthResponse.setPayId(sysNum);
            posCardPreAuthResponse.setSettleDate(result.getResult().getSettleDate());
            posCardPreAuthResponse.setReferenceNo(preAuthRequest.getReferenceNo());
            //收单机构
            posCardPreAuthResponse.setAcqInstCode(preAuthRequest.getCupsInstCode());
            //IC卡数据信息
            posCardPreAuthResponse.setIcData(result.getResult().getIcData());
            //发卡机构
            posCardPreAuthResponse.setPayAcctIssCode(result.getResult().getRcvInstCode());
            posCardPreAuthResponse.setTxnDate(preAuthRequest.getHeader().getTransDate());
            posCardPreAuthResponse.setTxnTime(preAuthRequest.getHeader().getTransTime());
        }
    }
}